package com.server.commons.security.Aspect;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.Header;
import com.server.common.code.utils.GsonUtils;
import com.server.common.code.vo.LoginVo;
import com.server.common.security.code.SecurityUtils;
import com.server.commons.rabbitmq.MyRabbitTemplate;
import com.server.commons.rabbitmq.constant.LogRabbitMQConstant;
import com.server.commons.rabbitmq.model.MyCorrelationData;
import com.server.common.security.code.utils.MapperAnnotationUtils;
import com.server.common.security.code.anntation.Log;
import com.server.model.all.system.bo.AddLogOperationBo;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.List;

@Aspect
@Component
public class LogAspect {

    @Resource
    private MyRabbitTemplate amqpTemplate;

    @Around("@annotation(com.server.common.security.code.anntation.Log)")
    public Object around(ProceedingJoinPoint point) throws Throwable {

        LoginVo loginVo = SecurityUtils.getLoginVo();

        Signature signature = point.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        Log log = method.getAnnotation(Log.class);

        if(ObjectUtils.isEmpty(log)){
            return point.proceed();
        }

        //方法
        String methodString = point.getTarget().getClass().getName()+"."+point.getSignature().getName();

        //接口路径
        List<String> values = MapperAnnotationUtils.getRequestMappingValue(method);

        //参数
        String parameter = GsonUtils.getGson().toJson(point.getArgs());

        //使用MQ
        AddLogOperationBo addLogOperationBo = AddLogOperationBo.builder()
                .method(methodString)
                .interfacePath(StrUtil.join(",",values))
                .parameter(parameter)
                .paramType(SecurityUtils.getHeader(Header.CONTENT_TYPE.getValue()))
                .userAgent(SecurityUtils.getHeader(Header.USER_AGENT.getValue()))
                .remoteIp(SecurityUtils.getIpAddress())
                .userId(ObjectUtils.isEmpty(loginVo)?null: loginVo.getUserId())
                .build();

        MyCorrelationData myCorrelationData = new MyCorrelationData();
        myCorrelationData.setExchangeName(LogRabbitMQConstant.LOG_EXCHANGE);
        myCorrelationData.setRoutingKey(LogRabbitMQConstant.USER_OPERATION_LOG_ROUTING_KEY);
        myCorrelationData.setBody(GsonUtils.getGson().toJson(addLogOperationBo));
        amqpTemplate.convertAndSend(myCorrelationData);

        return point.proceed();
    }

}
